﻿using Microsoft.Win32;
using System.Linq;

namespace AutoLoadDLL.ViewModel
{
    public static class CreateDemandLoading
    {
        /// <summary>
        /// 注册表操作
        /// </summary>
        /// <param name="appName">.NET程序名</param>
        /// <param name="appDesc">程序用途</param>
        /// <param name="appPath">.NET程序的路径</param>
        /// <param name="current_User">注册表项是创建在HKEY_CURRENT_USER键下
        /// 还是 HKEY_LOCAL_MACHINE键下</param>
        /// <param name="overWrite">是否覆盖同名的程序</param>
        /// <param name="flagLoadCtrls">LOCADCTRLS键的值</param>
        /// <returns></returns>
        public static bool CreateDemandLoadingEntries(string appName, string appDesc, string appPath,
            bool current_User, bool overWrite, int flagLoadCtrls)
        {
            if (appName == null)
            {
                return false;
            }
            //调用自定义函数，获取AutoCad所属的注册表键名
            var autoCadKeyName = GetAutoCadKeyName();
            //确定是HKEY_CURRENT_USER还是HKEY_LOCAL_MACHINE
            RegistryKey keyRoot = current_User ? Registry.CurrentUser : Registry.LocalMachine;
            //由于某些AutoCad版本的HKEY_CURRENT_USER可能不包括Applications键值，因此要创建该键值，如果已经存在该键
            //无需担心可能的覆盖操作问题，因为CreateSubKey函数会以写的方式打开他而不会执行覆盖操作
            RegistryKey keyApp = keyRoot.CreateSubKey(autoCadKeyName + "\\" + "Applications");
            //若存在同名的程序且选择不覆盖则返回
            if(!overWrite && keyApp.GetSubKeyNames().Contains(appName))
                return false;
            //创建相应的键并设置自动加载应用程序的选项
            RegistryKey keyUserApp = keyApp.CreateSubKey(appName);
            keyUserApp.SetValue("DESCRIPTION", appDesc, RegistryValueKind.String);
            keyUserApp.SetValue("LOADCTRLS", flagLoadCtrls, RegistryValueKind.DWord);
            keyUserApp.SetValue("LOADER", appPath, RegistryValueKind.String);
            keyUserApp.SetValue("MANAGED", 1, RegistryValueKind.DWord);
            keyUserApp.SetValue("RIBBON", 1, RegistryValueKind.DWord);
            //创建键成功则返回
            return true;    
        }
        /// <summary>
        /// 获取AutoCad所属的注册表键名
        /// </summary>
        /// <returns></returns>
        public static string GetAutoCadKeyName()
        {
            //获取HKEY_CURRENT_USER 键
            RegistryKey keyCurrentUser = Registry.CurrentUser;
            //打开HKEY_CURRENT_USER\Software\Autodesk\AutoCad键
            RegistryKey keyAutoCad = keyCurrentUser.OpenSubKey("Software\\Autodesk\\AutoCAD");
            //获得表示当前的AutoCad版本的注册表键值：如表示AutoCad2016的 R20.1
            string valueCurAutoCad = keyAutoCad.GetValue("CurVer").ToString();
            //如果未安装AutoCa，则返回
            if (valueCurAutoCad == null)
                return "";
            //获取HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD\R20.1 键
            RegistryKey keyCurAutoCad = keyAutoCad.OpenSubKey(valueCurAutoCad);
            //获取表示AutoCad当前语言的注册表键值：ACAD-a001:804
            string language = keyCurAutoCad.GetValue("CurVer").ToString();
            //获取AutoCad当前语言的注册表键：
            //HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD\R20.1\ACAD-a001:804
            RegistryKey keyLanguage = keyCurAutoCad.OpenSubKey(language);
            //返回去除HKEY_LOCAL_MACHINE前缀的当前AutoCAD 注册表项的键名
            //Software\Autodesk\AutoCAD\R20.1\ACAD-a001:804
            return keyLanguage.Name.Substring(keyCurrentUser.Name.Length + 1);
        }
        /// <summary>
        /// 删除注册表项
        /// </summary>
        /// <param name="appName">应用程序名</param>
        /// <param name="currentUser">若为true，则表示是对HKEY_CURRENT_USER注册表项进行操作，
        /// 若为false则表示对HKEY_CURRENT_MACHINE注册表进行操作</param>
        /// <returns></returns>
        public static bool RemoveDemandLoadingEntries(string appName , bool currentUser)
        {
            try
            {
                //获取AutoCad所属的注册表键名
                string cadName = GetAutoCadKeyName();
                //确定是HKEY_CURRENT_USER还是HKEY_CURRENT_MACHINE
                RegistryKey keyRoot = currentUser ? Registry.CurrentUser : Registry.LocalMachine;
                //以写的方式打开Applications注册表键
                RegistryKey keyApp = keyRoot.OpenSubKey(cadName + "\\" + "Applications", true);
                //删除指定名称的注册表键
                keyApp.DeleteSubKeyTree(appName);
            }
            catch (System.Exception ex)
            {
                //删除失败
                return  false;
            }
            //删除成功
            return true;
        }

    }
}
